package com.example.knowledgeget1.ChatCommon.Service;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.example.knowledgeget1.ChatCommon.Repository.NodeTypeRepository;
import com.example.knowledgeget1.ChatCommon.Request.ChatRequest;
import com.example.knowledgeget1.ChatCommon.Request.ChatRequestData;
import com.example.knowledgeget1.ChatCommon.Response.UserChatResponse;
import com.example.knowledgeget1.Util.NodeResponseLexer;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;

@Service
public class ChatService{

    private static final String url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";
    private static final String buildUrl = "http://localhost:8080/api/nodetypes/update/build";
    private static final String ApiKey = "sk-273f70a32e7647a5890925d82aa94a2b";
    private static final String unBuildUrl = "http://localhost:8080/api/nodetypes/update/unbuild";
    @Autowired
    private NodeTypeRepository nodeTypeRepository;


    @Async("taskExecutor2")
    public void chat(String courseName, String knowId, String knowName) throws IOException {
        String question = String.format("我在教学%s，请帮我生成关于知识点%s的讲解内容。回答时，直接用json格式进行封装，json格式中是一个列表，每一个列表项包括一个属性名和一个属性对应的内容，他们都是String类型，属性名应至少包括'介绍'、'代码示例'、'作用'、'语法'、'练习题'、'特点'、'推荐资料'，不需要额外的解释或者描述。", courseName, knowName);
        ChatRequest chatRequest = new ChatRequest(question);
        String json = JSONUtil.toJsonStr(chatRequest);

        CompletableFuture.supplyAsync(() -> {
                    return HttpRequest.post(url)
                            .header("Authorization", "Bearer " + ApiKey)
                            .header("Content-Type", "application/json")
                            .body(json)
                            .execute().body();
                }).thenApply(this::extractJsonFromResult)
                .thenAccept(result -> {
                    try {
                        NodeResponseLexer.Lexer(knowName, result);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).thenRun(() -> {
                    buildOrUnbuild(knowId, buildUrl);
                })
                .exceptionally(ex -> {
                    ex.printStackTrace();
                    return null;
                });
    }

    @Async("taskExecutor1")
    public void handleChatRequest(String courseName, String knowName) throws IOException {
        String id = String.valueOf(nodeTypeRepository.findByName(knowName).getId());

        buildOrUnbuild(id, unBuildUrl);

        String question = String.format("我在教学%s，请帮我生成关于知识点%s的讲解内容。回答时，直接用json格式进行封装，json格式中是一个列表，每一个列表项包括一个属性名和一个属性对应的内容，他们都是String类型，属性名应至少包括'介绍'、'代码示例'、'作用'、'语法'、'练习题'、'特点'、'推荐资料'，不需要额外的解释或者描述。", courseName, knowName);
        ChatRequest chatRequest = new ChatRequest(question);
        String json = JSONUtil.toJsonStr(chatRequest);

        String result = HttpRequest.post(url)
                .header("Authorization", "Bearer " + ApiKey)
                .header("Content-Type", "application/json")
                .body(json)
                .execute().body();

        result = extractJsonFromResult(result);
        NodeResponseLexer.Lexer(courseName, result);
        buildOrUnbuild(id, buildUrl);

        System.out.println("Chat completed.");
    }

    private void buildOrUnbuild(String id, String postUrl) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(postUrl);
            httpPost.setHeader("Content-type", "application/json; charset=UTF-8");
            httpPost.setHeader("Accept", "application/json");
            String jsonInputString;
            jsonInputString = id;
            httpPost.setEntity(new StringEntity(jsonInputString));

            HttpResponse response1 = httpClient.execute(httpPost);
            System.out.println("Response code: " + response1.getStatusLine().getStatusCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String extractJsonFromResult(String result) {
        // 使用正则表达式匹配JSON数据
        int start = result.indexOf("[");
        int end = result.lastIndexOf("]");

        result = result.substring(start, end + 1);
        result = result.replaceAll("\\\\\\\\n", "\u0001"); // 将需要保留的转义序列暂时替换成特殊字符
        result = result.replaceAll("\\\\\\\\\\\\\"", "\u0002");
        result = result.replaceAll("\\\\n", ""); // 移除\n转义
        result = result.replaceAll("\\\\", ""); // 移除\"转义
        result = result.replaceAll("\u0001", "\\\\\\\\n"); // 恢复需要保留的转义序列
        result = result.replaceAll("\u0002", "\\\\\\\\\\\\\"");
        return result;
    }

    // 用户chat
    public UserChatResponse userChat(String userId, String message) throws Exception {
        // 创建messages JSON数组
        JSONArray messages = new JSONArray();
        JSONObject system_message = new JSONObject().put("role", "system").put("content", "You are a helpful assistant.");
        messages.put(system_message);
        JSONObject user_message = new JSONObject().put("role", "user").put("content", message);
        messages.put(user_message);

        // 构建请求体
        JSONObject body = new JSONObject()
                .put("model", "qwen-turbo")
                .put("input", new JSONObject().put("messages", messages))
                .put("parameters", new JSONObject().put("result_format", "message"));

        // 调用模型
        JSONObject assistant_output = get_response(body);

        // 处理返回值
        JSONObject output = assistant_output.getJSONObject("output");
        JSONArray choices = output.getJSONArray("choices");
        JSONObject firstChoice = choices.getJSONObject(0);
        JSONObject assistant_message = firstChoice.getJSONObject("message");
        String content = assistant_message.getString("content");

        // 返回响应
        return new UserChatResponse(userId, content);
    }

    // 封装模型响应函数
    public static JSONObject get_response(JSONObject body) throws Exception {
        URL posturl = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) posturl.openConnection();

        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Authorization", "Bearer " + ApiKey);
        connection.setDoOutput(true);

        String jsonInputString = body.toString();
        try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
            wr.write(jsonInputString.getBytes(StandardCharsets.UTF_8));
            wr.flush();
        }

        StringBuilder response = new StringBuilder();
        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()))) {
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
        }
        JSONObject response_json = new JSONObject(response.toString());
        connection.disconnect();
        return response_json;
    }
}
